import sys
parent_dir = "../pygl"
sys.path.append(parent_dir)
import glfw
import OpenGL.GL as gl
import glm
import imgui
import numpy as np
from PIL import Image
from common.app_v2 import App
import pygl

class AxesApp(App):
    # 初始化着色器，vao vbo等
    def setupVertex(self) -> None:
        self.program = pygl.ProgramVF("basic/shaders/axes.vs", 
                                      "basic/shaders/axes.fs")
        self.axis_length = 1.0
        self.axis_width = 1.0
        vertices = np.array([
            0.0, 0.0, 0.0, self.axis_length, 0.0, 0.0,
            0.0, 0.0, 0.0, 0.0, self.axis_length, 0.0,
            0.0, 0.0, 0.0, 0.0, 0.0, self.axis_length
        ], dtype=gl.GLfloat)
        colors = np.array([ 
            1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
            0.0, 1.0, 0.0, 0.0, 1.0, 0.0,
            0.0, 0.0, 1.0, 0.0, 0.0, 1.0
        ], dtype=gl.GLfloat)
        self.vao = pygl.VertexArrayObject()
        self.position_vbo = pygl.VertexBufferObject(vertices)
        self.color_vbo = pygl.VertexBufferObject(colors)
        position_binding_point = 0
        color_binding_point = 1
        self.vao.setVertexBuffer(self.position_vbo, position_binding_point, 
                                 0, 3 * gl.sizeof(gl.GLfloat))
        self.vao.setVertexBuffer(self.color_vbo, color_binding_point, 0, 
                                 3 * gl.sizeof(gl.GLfloat))
        attribute_position = pygl.VertexAttribute("position", 0, 3, 
                                                  gl.GL_FLOAT, False, 0)
        attribute_color = pygl.VertexAttribute("color",1, 3, gl.GL_FLOAT, 
                                               False, 0)
        self.vao.setVertexAttribute(position_binding_point, attribute_position)
        self.vao.setVertexAttribute(color_binding_point, attribute_color)
        self.rotation = glm.vec3(0.0, 0.0, 0.0)
        self.position = glm.vec3(0.0, 0.0, 0.0)
        self.scale = glm.vec3(1.0, 1.0, 1.0)
        self.theta = 0.01
        self.phi = 0.01
        self.rotation_active = True
        self.r_key_pressed = False
        self.s_key_pressed = False

    # 配置imgui界面元素
    def showImGui(self)->None:
        imgui.begin("设置")
        imgui.text("按R键可以重置，按S键可以在\n开始旋转和停止旋转之间切换")
        if imgui.button("重置"):
            self.rotation = glm.vec3(0.0, 0.0, 0.0)
        if imgui.button("开始旋转" if self.rotation_active else "停止旋转"):
            self.rotation_active = not self.rotation_active
        _, self.axis_width = imgui.slider_float("坐标轴线宽", 
                                    self.axis_width, 1.0, 10.0)
        _, color = imgui.color_edit3("背景颜色", self.background_color.x, 
                                     self.background_color.y, 
                                     self.background_color.z)
        self.background_color = glm.vec4(color[0], color[1], color[2], 1.0)
        imgui.end()     

    # 渲染图形
    def render(self) -> None:
        gl.glClearNamedFramebufferfv(0, gl.GL_COLOR, 0, 
                                     self.background_color.to_tuple())
        self.program.use()
        self.vao.bind()
        translation_matrix = glm.translate(self.position)
        if not self.rotation_active:
            self.rotation.x += self.theta
            self.rotation.y += self.phi
        rotation_matrix = glm.rotate(glm.radians(self.rotation.x), 
                                     glm.vec3(1.0, 0.0, 0.0))
        rotation_matrix = glm.rotate(rotation_matrix, 
            glm.radians(self.rotation.y), glm.vec3(0.0, 1.0, 0.0))
        rotation_matrix = glm.rotate(rotation_matrix, 
            glm.radians(self.rotation.z), glm.vec3(0.0, 0.0, 1.0))
        scale_matrix = glm.scale(self.scale)
        self.model = translation_matrix * rotation_matrix * scale_matrix
        view = glm.mat4(1.0)
        view = glm.translate(view, glm.vec3(0.0, 0.0, -3.0))
        projection = glm.perspective(glm.radians(45.0), 
                float(self.width)/self.height, 0.1, 100.0)
        self.program.setUniformMatrix4fv(0, self.model)
        self.program.setUniformMatrix4fv(1, view)
        self.program.setUniformMatrix4fv(2, projection)
        gl.glLineWidth(self.axis_width)
        gl.glDrawArrays(gl.GL_LINES, 0, 6)

    # 释放资源
    def cleanup(self) -> None:
        self.position_vbo.delete()
        self.color_vbo.delete()
        self.vao.delete()
        self.program.delete()

    def keyInput(self)-> None:
        if glfw.get_key(self.window, glfw.KEY_S) == glfw.PRESS and \
                    not self.s_key_pressed:
            self.rotation_active = not self.rotation_active
            self.s_key_pressed = True
        if glfw.get_key(self.window, glfw.KEY_S) == glfw.RELEASE:
            self.s_key_pressed = False
        if glfw.get_key(self.window, glfw.KEY_R) == glfw.PRESS and \
                    not self.r_key_pressed:
            self.rotation = glm.vec3(0.0, 0.0, 0.0)
            self.r_key_pressed = True
        if glfw.get_key(self.window, glfw.KEY_R) == glfw.RELEASE:
            self.r_key_pressed = False
        super().keyInput()

if __name__ == "__main__":
    app = AxesApp(100, 100, 800, 600, "你好，坐标轴App！")
    app.run()

